﻿#include "GraphicsTool/DatasPublic.h"
#include "GraphicsTool/NoLockPool.h"

#include "GraphicsTool/COctreeManager.h"

#include <fstream>
#include <future>

NoLockPool::NoLockPool()
{
	mStop = false;
	mCOctreeSceneManager = nullptr;
	mIndex = 0;
}

void NoLockPool::Run()
{
	while (!mStop)
	{
		popTask();

		std::unique_lock<std::mutex> loc(mMutex);
		if (mqueue.empty())
		{
			mConditional.wait(loc);
		}
	}
}

NoLockPool::~NoLockPool()
{
	shutdown();
}

void NoLockPool::init(int numThreads)
{
	for (size_t i = 0; i < numThreads; i++)
	{
		mThreads.push_back(std::thread(&NoLockPool::Run, this));
	}
}
void NoLockPool::pushTask(std::function<void(COctree *, COctreeNode *, COctreeNode *, std::vector<COctreeNode*>&)>& task)
{
	//一下子全部填满
	std::unique_lock<std::mutex> loc(mMutex);
	//mqueue.push(std::move(task));

	mqueue.push([this](COctree * octree, COctreeNode * node1, COctreeNode * node, std::vector<COctreeNode*>& desNodes){
	
		mCOctreeSceneManager->findNodes(octree, node1, node, desNodes);
	});

	mConditional.notify_one();
}

void NoLockPool::pushTask()
{
	//一下子全部填满
	{
		std::unique_lock<std::mutex> loc(mMutex);

		mqueue.push([this](COctree * octree, COctreeNode * node1, COctreeNode * node, std::vector<COctreeNode*>& desNodes){

			mCOctreeSceneManager->findNodes(octree, node1, node, desNodes);
		});
	}

	mConditional.notify_one();
}
void NoLockPool::resetPool()
{
	mIndex++;

	while (!mqueue.empty())
	{
		mqueue.pop();
	}

}
//每个线程都会调用
void NoLockPool::popTask()
{
	std::function<void(COctree *, COctreeNode *, COctreeNode *, std::vector<COctreeNode*>&)> task;

	{
		std::unique_lock<std::mutex> loc(mMutex);

		if (mqueue.empty() || !mCOctreeSceneManager)
		{
			mConditional.wait(loc);
		}

	
		task = std::move(mqueue.front());
		mqueue.pop();

	}

	if (mCOctreeSceneManager)
	{
		std::vector<COctreeNode*> desNodes;
		COctreeNode* node = mCOctreeSceneManager->mTotalNodes[mIndex++];
		{
			task(mCOctreeSceneManager->mOctree, node, node, desNodes);

			std::unique_lock<std::mutex> loc(mMutex);

			(*mCollisionNode)[node] = desNodes;
		}

		if (mIndex == mCOctreeSceneManager->mTotalNodes.size() - 1)
		{
			shutdown();
		}
	}



}

void NoLockPool::shutdown()
{
	{
		std::unique_lock<std::mutex> loc(mMutex);
		mStop = true;
	}

	mConditional.notify_all();

	for (int i = 0; i < mThreads.size(); ++i)
	{
		if (mThreads.at(i).joinable())
		{
			//运行完，再运行主线程
			mThreads.at(i).join();
		}
	}

}

